﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<link rel="Stylesheet" type="text/css" media="screen" href="Screen.css" />
  <title>StpCallback_TransmitGetBuffer</title>
</head>
<body>
	<h3>StpCallback_TransmitGetBuffer</h3>
	<hr />
<pre>
void* StpCallback_TransmitGetBuffer
(
    const STP_BRIDGE* bridge,
    unsigned int      portIndex,
    unsigned int      bpduSize,
    unsigned int      timestamp
);
</pre>
	<h4>
		Summary</h4>
	<p>
		Used together with <a href="StpCallback_TransmitReleaseBuffer.html">
		StpCallback_TransmitReleaseBuffer</a> to transmit a BPDU generated by the STP library.</p>
	<h4>
		Parameters</h4>
	<dl>
		<dt>bridge</dt>
		<dd>The application receives in this parameter a pointer to the bridge object returned by
			<a href="STP_CreateBridge.html">STP_CreateBridge</a>.</dd>
		<dt>portIndex</dt>
		<dd>The application receives in this parameter the zero-based index of the port
			from which the BPDU is to be transmitted.</dd>
		<dt>bpduSize</dt>
		<dd>The size of the BPDU packet, excluding non-STP headers. See the Remarks section for more
			information.</dd>
		<dt>timestamp</dt>
		<dd>The application receives in this parameter the timestamp that it passed to the function
			that called this callback (STP_OnBpduReceived, STP_OnPortEnabled etc.)
			Useful for debugging and troubleshooting.</dd>
	</dl>
	<h4>Return Value</h4>
		<p>The application must return either:</p>
	<ul>
		<li>a pointer to a buffer where the STP library will construct the BPDU to be sent, or</li>
		<li>NULL, if the application wants to discard the BPDU.</li>
	</ul>
	<p>The application might want to discard a BPDU, for instance, when it knows that a
		port is hardwired to a non-STP device and wants to save bandwidth by not sending
		BPDUs to that port.</p>
	<h4>
		Remarks</h4>
		<p>
			This callback, together with <a href="StpCallback_TransmitReleaseBuffer.html">
		StpCallback_TransmitReleaseBuffer</a>, is used for transmitting BPDUs generated by the
			STP library. They are designed this way (GetBuffer/ReleaseBuffer) to allow the STP library
			to work with zero-copy Ethernet drivers. Such Ethernet drivers have similar
			GetBuffer/ReleaseBuffer routines, and these routines allow the software to construct
			Ethernet packets directly in the DMA memory of the Ethernet controller (hence the name
			&quot;zero-copy&quot;).</p>
	<p>
			If a zero-copy Ethernet driver is not available, then this callback
			should return a pointer
			to a RAM-based buffer, for instance a static variable of type &quot;byte array&quot;. This
			buffer must be large enough to contain the non-STP headers and the largest BPDU
			that the STP library might request (see below).</p>
	<p>
			An embedded application must prepend a non-STP header to the BPDU (see below). So unless your
			particular Ethernet driver prepends
			part of this header itself, this function should obtain a longer buffer, construct the non-STP header in the first bytes, and return
			a pointer that points just after the non-STP header.</p>
	<p>
			The non-STP header has the following format:</p>
	<ul>
		<li>6 bytes for the destination MAC address, which for BPDU packets is always 01-80-C2-00-00-00.</li>
		<li>6 bytes for the MAC address of the
			port from which this BPDU should be sent. The application can generate this MAC
			address, for example, by <a href="STP_GetBridgeAddress.html">getting the bridge&#39;s MAC address</a> and adding <code>1+portIndex</code>
			to its last byte.</li>
		<li>On most switches (not on Microchip KSZ ones, see below), here goes
			a hardware-specific &quot;tag&quot; structure, typically 4 or 8 bytes, which tells the switch IC which
			port to transmit this BPDU out of. Refer to the datasheet of the switch IC for
			information about the format of this structure. Also read about the port mapping in
			the Remarks section of the <a href="STP_OnPortEnabled.html">STP_OnPortEnabled</a> function.
			Examples:<ul>
				<li>For the <strong>IP175C</strong> switch IC, this header could be
					<code style="white-space:nowrap">0x81,&nbsp;(1 &lt;&lt; portIndex),&nbsp;0x00,&nbsp;0x00</code>.</li>
				<li>For the <strong>AR8328</strong> switch IC, this header could be
					<code style="white-space:nowrap">0xAA,&nbsp;0xAA,&nbsp;0x80,&nbsp;0x80&nbsp;|&nbsp;(1&nbsp;&lt;&lt;&nbsp;(1&nbsp;+&nbsp;portIndex))</code>.</li>
				<li>For the <strong>88E6352</strong> switch IC, this header could be <code>0x91, 0x00, 0x00, 0x00, 0x40,
			portIndex &lt;&lt; 3, 0x00, 0x00</code>.</li>
			</ul>
		</li>
		<li>2 bytes for EtherType/Size field. This should be <code>3&nbsp;+&nbsp;bpduSize</code>. (3
			is the size of the following LLC field.) This field must be written in network byte order: MS byte, then LS byte.</li>
		<li>3 bytes for the LLC field, which normally are 0x42, 0x42, 0x03.</li>
	</ul>

	<p>
		On some
		Microchip switches (KSZxxxx), the tag is not located in the headers, but instead
		in a byte at the end of the frame, after the BPDU, after any padding your
		Ethernet peripheral might append in order to extend your frame to 64 bytes,
		and before the CRC.
		The name of this functionality in Microchip datasheets is Tail Tagging.
		You can find a sample implementation in the TestAppMK66F+KSZ8794 directory.</p>
	<p>
			The largest <code>bpduSize</code> that the STP library requests can be calculated from §14.4 in
			802.1Q-2018:</p>
	<ul>
		<li>for Legacy STP mode: 35 bytes;</li>
		<li>for RSTP mode: 36 bytes;</li>
		<li>for MSTP mode: <code>102 + 16 * <a href="STP_CreateBridge.html">mstiCount</a></code>, so up to 1126 bytes in case of 64 MSTIs.</li>
	</ul>
	<p>
		If this callback returns an address other than NULL, the STP library will construct
		a BPDU at the returned address and will call
		<a href="StpCallback_TransmitReleaseBuffer.html">StpCallback_TransmitReleaseBuffer</a>
		afterwards.</p>
	<p>
		If this callback returns NULL, the STP library
		won&#39;t write its BPDU and won&#39;t call <a href="StpCallback_TransmitReleaseBuffer.html">StpCallback_TransmitReleaseBuffer</a>
		afterwards.</p>
	<p>
		Losing of too many BPDUs in a network can cause Ethernet loops to be formed, resulting in
		immediate flooding of that network. For this reason, it is recommended that BPDUs are sent
		via some high-priority channel of the Ethernet driver; if the Ethernet driver does not
		know about priorities, it is recommended that this function waits in case Ethernet
		transmission is currently unavailable (due to full TX buffers, for example).</p>

</body>
</html>
